﻿using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using AutoMapper;
using ESSManageService.Common.Helper;
using ESSManageService.Enum.DBEnum;
using ESSManageService.IServices;
using ESSManageService.IServices.IDBServices;
using ESSManageService.Model;
using ESSManageService.Model.DBModels.Info;
using ESSManageService.Model.ViewModels;
using ESSManageService.Services.DBServices;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;

namespace ESSManageService.API.Controllers
{
    /// <summary>
    /// 登录控制器，提供与登录相关的 API 接口
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Produces("application/json")]
    [AllowAnonymous] // 允许匿名访问
    public class LoginController : BaseApiController
    {
        private readonly IMapper _mapper;
        private readonly ILogger<LoginController> _logger;
        readonly IRoleServices _roleServices;
        readonly IUserInfoServices _userInfoServices;
        private readonly ITokenBlacklistService _tokenBlacklistService;

        public LoginController(IMapper mapper, ILogger<LoginController> logger
            , IRoleServices roleServices, IUserInfoServices userInfoServices
            , ITokenBlacklistService tokenBlacklistService)
        {
            _mapper = mapper;
            _logger = logger;
            _roleServices = roleServices;
            _userInfoServices = userInfoServices;
            _tokenBlacklistService = tokenBlacklistService;
        }

        [HttpPost]
        public MessageModel<string> Login([FromBody] LoginModel model)
        {
            // 验证用户凭据
            ;
            if (!_userInfoServices.GetUserRoleNameStr(model.LoginName, model.LoginPWD))
            {
                //return Unauthorized();
                return new MessageModel<string>
                {
                    msg = "登录名或密码错误",
                };
            }

            var userinfo = _userInfoServices.GetUserInfo(model.LoginName, model.LoginPWD);
            var roles = _roleServices.GetAllRoles();
            string userRole = roles.First(item => item.Id == userinfo.RoleID).Name;
            if (userRole == "管理者")
                userRole += ",教练员";
            var claims = new[]
            {
                new Claim(ClaimTypes.Name, model.LoginName),
                new Claim(ClaimTypes.NameIdentifier, userinfo.Id.ToString()),
                //new Claim(ClaimTypes.Role, roles.First(item=>item.Id==userinfo.RoleID).Name),
            };

            // 可以将一个用户的多个角色全部赋予；  
            claims = claims.Concat(userRole.Split(',').Select(s => new Claim(ClaimTypes.Role, s))).ToArray();
            claims.Append(new Claim(JwtRegisteredClaimNames.Jti, userinfo.Id.ToString()));
            /*return Ok(new
            {
                token = new JwtSecurityTokenHandler().WriteToken(token),
                expiration = expiry
            });
*/
            /*IActionResult response = new OkObjectResult(new
            {
                token = new JwtSecurityTokenHandler().WriteToken(token),
                expiration = expiry
            });*/

            return Success<string>(new JwtSecurityTokenHandler().WriteToken(_tokenBlacklistService.IssueJwt(claims,out DateTime localExpiry)).ToString(),$"令牌有效期至：{localExpiry:yyyy-MM-dd HH:mm:ss}（本地时间）");
        }

        [HttpPost]
        public async Task<MessageModel<string>> SignOut()
        {
            try 
            {
                // 获取当前令牌
                var authorizationHeader = HttpContext.Request.Headers["Authorization"].ToString();
                if (string.IsNullOrEmpty(authorizationHeader) || !authorizationHeader.StartsWith("Bearer "))
                {
                    _logger.LogWarning("无效的授权头格式");
                    return new MessageModel<string>
                    {
                        status = 1002,
                        msg = "授权头格式应为：Bearer [token]",
                        data = null
                    };
                }

                var token = authorizationHeader.Substring("Bearer ".Length).Trim();
                
                // 将令牌加入黑名单
                await _tokenBlacklistService.AddToBlacklistAsync(token);

                // 解析令牌获取用户信息
                var principal = _tokenBlacklistService.GetPrincipalFromToken(token);
                var username = principal?.Identity?.Name ?? "未知用户";
                _logger.LogInformation($"用户 {username} 已注销，令牌已失效");

                return new MessageModel<string>
                {
                    status = 1001,
                    msg = "注销成功",
                    data = null
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "注销失败");
                return new MessageModel<string>
                {
                    status = 1003,
                    msg = "注销操作异常",
                    data = ex.Message
                };
            }
        }

    }
}
